/**
 * 
 */
package com.googlecode.dynargs.util;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;

import com.googlecode.dynargs.model.type.ObjectField;
import com.googlecode.dynargs.model.type.ObjectType;
import com.googlecode.dynargs.model.type.Type;

/**
 * @author Federico De Faveri defaveri@gmail.com
 *
 */
public class PrettyPrinter {
	
	private static final PrettyPrinter INSTANCE = new PrettyPrinter();
	
	public synchronized static void prettyPrint(Type type)
	{
		INSTANCE.startPrint(type);
	}
	
	protected IndentedWriter writer;
	protected Queue<Type> toPrint;
	protected Set<Type> saw;
	
	private PrettyPrinter()
	{
		writer = new IndentedWriter();
		toPrint = new LinkedList<Type>();
		saw = new HashSet<Type>();
	}
	
	protected void clean()
	{
		writer.setIndentation(0);
		toPrint.clear();
		saw.clear();
	}
	
	private void startPrint(Type type)
	{
		clean();
		toPrint.add(type);
		while(!toPrint.isEmpty()) {
			Type typeToPrint = toPrint.remove();
			print(typeToPrint);
		}
	}
	
	private void print(Type type)
	{
		saw.add(type);
		if (type instanceof ObjectType) {
			ObjectType objectType = (ObjectType)type;
			writer.println(type.getId()+" {");
			writer.inc();
			for (ObjectField field:objectType.getFields()) {
				Type fieldType = field.getType();
				if (!saw.contains(fieldType)) {
					toPrint.add(fieldType);
					saw.add(fieldType);
				}
				writer.println(fieldType.getId()+" "+field.getName()+";");
			}
			
			writer.dec();
			writer.println("}");
			
		}
	}

}
